﻿using Cysharp.Threading.Tasks;
using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

namespace IQIGame.Onigao.Framework
{
    public class ExText : Text, IUGUIEx
    {
        [SerializeField]
        private bool _isAutoI18N;
        [SerializeField]
        private long _guid;

        /// <summary>
        /// 设计原理参考UITextItemInfoEditor.CheckExistExText，暂时保留
        /// </summary>
        public long tid => _guid;
        public bool isAutoI18N
        {
            set { _isAutoI18N = value; }
            get { return _isAutoI18N; }
        }

        public object dynamicData { get; set; }

        public void SetActive(bool isActive)
        {
            this.gameObject.SetActive(isActive);
        }

#if UNITY_EDITOR
        /// <summary>
        /// 在手动添加组件时，处理一次创建事件
        /// 通过菜单创建或通过复制粘贴创建的逻辑都通过ExTextHierarchyHelper处理，也就是说UI编辑时大部分创建逻辑其实都不是通过Reset实现的
        /// 添加组件时，其GameObject已经被加入老节点了，所以该操作无需做其他额外处理，所谓加入老节点的意思参考ExTextHierarchyHelper的实现原理
        /// </summary>
        protected override void Reset()
        {
            base.Reset();
            OnCreate();
        }

        /// <summary>
        /// 修改了组件数据时
        /// </summary>
        protected override void OnValidate()
        {
            base.OnValidate();
            CheckDelay().Forget();
        }

        private async UniTask CheckDelay()
        {
            //修改往往不能同步体现，要延迟一帧修改数据才能通过预设接口获取到
            await UniTask.DelayFrame(1);
            //检查是否是覆盖了源预设的text，如果是要重新为guid赋值
            //如果text没有修改，但guid却不一样（常见于撤销修改），把guid还原
            CheckKeyFieldModifiedFromPrefab(out bool isTextModified, out bool isGuidModified);
            if (isTextModified || isGuidModified)
            {
                var sourceObj = PrefabUtility.GetCorrespondingObjectFromSource(this.gameObject);
                var sourceGuid = sourceObj.GetComponent<ExText>()._guid;
                if (isTextModified)
                {
                    if (sourceGuid == _guid)
                    {
                        _guid = GetAnGUID();
                    }
                }
                else if (isGuidModified)
                {
                    _guid = sourceGuid;
                }
            }
        }

        /// <summary>
        /// 检查关键数据是否覆盖了源预设
        /// 如果不属于任何内嵌预设，两个out参数都固定是false
        /// </summary>
        /// <param name="isTextModified"></param>
        /// <param name="isGuidModified"></param>
        public void CheckKeyFieldModifiedFromPrefab(out bool isTextModified, out bool isGuidModified)
        {
            isTextModified = false;
            isGuidModified = false;
            //由于这个方法存在延迟调用，所以要判断对象是否销毁
            if (this == null)
            {
                return;
            }
            bool hasOverride = PrefabUtility.HasPrefabInstanceAnyOverrides(this.gameObject, false);
            if (hasOverride)
            {
                var modifications = PrefabUtility.GetPropertyModifications(this.gameObject);
                if (modifications != null && modifications.Length > 0)
                {
                    foreach (var modification in modifications)
                    {
                        if (modification.propertyPath == "m_Text")
                        {
                            isTextModified = true;
                        }
                        else if (modification.propertyPath == nameof(_guid))
                        {
                            isGuidModified = true;
                        }
                        if (isTextModified && isGuidModified)
                        {
                            break;
                        }
                    }
                }
            }
        }

        public void OnCreate()
        {
            _guid = GetAnGUID();
        }

        public long GetAnGUID()
        {
            return (long)DateTime.UtcNow.Subtract(DateTime.UnixEpoch).TotalMilliseconds;
        }
#endif
    }
}
